<?
    /* -*- Mode: PHP5; tab-width: 4; indent-tabs-mode: nil; basic-offset: 4 -*- */
    
    /*********************************************************
    *            --== InArch ==--
    *
    * @author Kulikov Alexey <a.kulikov@gmail.com>
    * @version n/a
    * @since 11.06.2005
    * @copyright essentialmind.com 2005
    *
    *********************************************************/
    
    /***
    * Class searchIndex
    ****
    * This class controls the creation of the solution's search
    * index.
    *
    * Yes it needs thought and probably a lot of refactoring!
    ****
    * @package search
    * @author A Kulikov <a.kulikov@gmail.com>
    * @version n/a
    * @since 11.06.2005
    * @copyright essentialmind.com 2005
    ***/
    class searchIndex{
        
        /**
         * Reference to an open DB connection
         *
         * @var ADOConnection
         */
        private $db;
        
        /**
         * Reference to a log writer
         *
         * @var object
         */
        private $log;

        
        /**
         * Constructor
         *
         * @param ADOConnection $db
         * @param object $log
         */
        public function __construct(ADOConnection $db,$log){
            $this->db       = $db;
            $this->log      = $log;
        }   
        
        
        /**
         * Creates a records in the search index based on a pageid from the
         * pagemap table and some sort of text
         *
         * @param integer $pageid
         * @param string $text
         * @return boolean
         */
        public function pushToIndex($pageid, $text){
            try{
                //get URL data from the database ;)
                $pageData = $this->db->getRow("SELECT 
                                                    pagemap.id,
                                                    pagemap.nodeid,
                                                    pagemap.pageid,
                                                    get_path(nodeid)||pageurl||'.html' AS url,
                                                    pagemap.title,
                                                    datatype.codeset
                                               FROM pagemap LEFT JOIN datatype ON pagemap.pagetype = datatype.id WHERE pagemap.id = ".(int)$pageid);
                
                //do we rock?
                if(empty($pageData)){
                    throw new Exception("No page with an ID: ".(int)$pageid." in the database!");
                }
                
                //first dump the old index (if any)
                $this->pullFromIndex($pageData['id']);
                
                //smash the title and the text together
                $text = $pageData['title'] . ' ' . $text;

                /*
                    Cook the index content!
                */
                //strip data of useless stuff such as
                //$text   = iconv('ISO-8859-1','UTF-8',$text);

                //new lines
                $text   = $this->stripNewLines($text);
                
                //tags
                $text   = strip_tags($text);
                
                //punctuation marks
                $text   = $this->stripPunctuation($text);
                
                //string to lower the stuff
                $text   = strtolower($text);
                
                //words shorter than three letters and repeating words
                $text   = $this->stripClones($text);
                /*
                    End the cooking session ;)
                */
                
                //hurray, create a record in the db
                $this->db->Execute("INSERT INTO searchindex(pageid,longindex) VALUES(".$pageData['id'].",'$text')");
                
                //log action
                $this->log->recordAction("Created search index for page ID: " . (int)$pageid);
                
                //report success
                return true;
            }catch (exception $e){
                //record error message
                $this->log->recordError($e->getMessage(),$e->getCode());
                
                //report failure
                return false;
            }
        }
        
        
        /**
         * Deletes a record from the Search Index based on some pageid
         *
         * @param integer $pageid
         * @return bool
         */
        public function pullFromIndex($pageid){
            try{
                //drop the index
                $this->db->Execute("DELETE FROM searchindex WHERE pageid = ".(int)$pageid);
                
                //log action
                $this->log->recordAction("Trashed Search Index for page ID: " . (int)$pageid);
                
                //report success
                return true;
            }catch (exception $e){
                //record error message
                $this->log->recordError($e->getMessage(),$e->getCode());
                
                //report failure
                return false;
            }
        }
        
        
     
        /**
         * Strips a string of all the new lines, end text charachters and tab characters
         *
         * @param string $text
         * @return string
         */
        private function stripNewLines($text){
            return str_replace('\n',' ',str_replace('\r',' ',str_replace('\z',' ',str_replace('\t',' ',$text))));
        }
        
        
        /**
         * Removes punctuation from a string
         *
         * @param string $text
         * @return string
         */
        private function stripPunctuation($text){
            //please note, that a set of str_replace functions is
            //reasonable faster than regular expressions
            $text=str_replace ('-', ' ', $text);
            $text=str_replace ('.', ' ', $text);
            $text=str_replace (',', ' ', $text);
            $text=str_replace ('!', ' ', $text);
            $text=str_replace ('?', ' ', $text);
            $text=str_replace (':', ' ', $text);
            $text=str_replace (';', ' ', $text);
            $text=str_replace (')', ' ', $text);
            $text=str_replace ('(', ' ', $text);
            $text=str_replace ('"', ' ', $text);
            $text=str_replace ('@', ' ', $text);
            $text=str_replace ('\'', ' ', $text);
            
            return $text;
        }
        
        
        /**
         * Enter description here...
         *
         * @param string $text
         * @return string
         */
        private function stripClones($text){
            //cteate an array of the content
            $text=explode(" ", $text);
            
            //kill anything that is shorter than 3 letters
            array_walk ($text, 'sw');

            //remove clones
            $text = array_unique($text);
            
            //return data
            return implode(" ", $text);
        }
    }
    
    //used by array_walk in the class
    function sw(&$data){
        if(strlen($data) < 3){
            $data = null;  
        }
    }
?>